9.05. Типы данных
Типы данных
Текст (строка) - str, string
Целое число - int, integer
Число с запятой - float
Булево значение - True, False
Ничего - None или null
Что такое переменная
Что такое память и зачем программе память
Как переменная "бронирует" участок памяти и записывает туда данные, а размер "брони" определяется типом
Добавить mermaid схему
Добавить задачи
Представьте, что вы пришли в большую библиотеку. Там тысячи книг, но каждая лежит на своём месте: художественные — в одном зале, учебники — в другом, энциклопедии — в третьем. Если бы книги лежали просто вперемешку, искать нужную было бы почти невозможно. Компьютер устроен похоже: когда он работает с информацией, ему важно понимать, с чем именно он имеет дело — с текстом, числом, правдой или ложью. Иначе он не сможет правильно это использовать.
Это и есть типы данных — правила, которые помогают программе понимать, какого рода информация хранится в том или ином месте. Без них компьютер был бы как ребёнок, которому дали пульт от телевизора и сказали: «Нажми на кнопку» — но не объяснили, какую кнопку и зачем.
Давайте разберёмся по порядку — от простого к чуть более сложному, но всё равно понятному.
Что такое переменная?
Прежде чем говорить о типах, нужно понять, куда вообще попадает информация. Ответ — в переменную.
Переменная — это как ярлык на коробке. Сама коробка — это участок памяти компьютера. А ярлык — имя переменной, например возраст, имя, лайкнуто. В коробку можно положить что-то одно: число, слово, галочку «да/нет» — и потом обращаться к этому содержимому через ярлык.
Пример:
имя = "Алиса"
возраст = 12
любит_роботов = True
Здесь:
имя— переменная, в которой лежит текст"Алиса";возраст— переменная со значением12;любит_роботов— переменная, в которой записан ответ на вопрос «любит ли Алиса роботов?» — и ответTrue(«да»).
Важно: переменная — это не то же самое, что значение. Это контейнер для значения. И как контейнеры бывают разного размера и назначения (стакан для воды, банка для варенья, чемодан для вещей), так и переменные бывают разного типа — потому что хранят разное.
А что такое память? Зачем программе вообще что-то запоминать?
Компьютер — это гигантский, очень быстрый счётчик и сортировщик. Он ничего не «помнит» сам по себе — как стиральная машина не помнит, какую программу вы запускали вчера, пока вы снова не нажмёте кнопку.
Когда программа запускается, ей нужно где-то хранить промежуточные результаты:
- что ввёл пользователь;
- сколько очков набрал игрок;
- как зовут персонажа;
- завершилась ли игра.
Для этого выделяется оперативная память (RAM) — временный склад данных. Пока программа работает, информация живёт там. Когда программа закрывается — память освобождается, как будто вы вынесли весь мусор из мастерской после ремонта.
Каждая переменная — это запрос на бронирование кусочка этой памяти. Но важно:
🔹 компьютер не может просто «отрезать кусок памяти на глаз» — он должен знать, сколько именно байтов нужно;
🔹 и как эти байты потом интерпретировать — как текст? как число? как да/нет?
Именно поэтому тип данных — это не просто ярлык вроде «число» или «текст». Это техническое указание:
- сколько памяти занять (например, целое число от −2 млрд до +2 млрд требует 4 байта);
- как хранить биты внутри (например, число 65 и буква
A— это одни и те же 8 бит:01000001, но в одном случае это число, в другом — символ); - какие операции с этим можно делать (складывать числа — можно, складывать тексты — тоже, но по-другому; а к
Trueприбавить"кот"— нельзя вообще — будет ошибка).
Это и есть типизация — система правил, по которым компьютер понимает: что здесь лежит и что с этим можно делать.
Теперь — главные герои: основные типы данных
1. Текст (строка) — str, string
Что это? Любая последовательность символов внутри кавычек: "Привет!", '123', "🚀🤖🔥".
Обратите внимание: даже если внутри кавычек стоит число — это не число, а текст. "100" + "5" даст "1005", а не 105. Нельзя умножить "кот" на 3 (в большинстве языков), но можно повторить его три раза: "кот" * 3 → "коткоткот" — и это уже не арифметика, а операция над строками.
Как хранится? Каждый символ кодируется числом (чаще всего по стандарту UTF-8). Буква А — это 192, a — 97, пробел — 32, смайлик 🤖 — 4 байта. Чем длиннее строка — тем больше памяти она занимает.
Примеры использования:
- Имя пользователя:
"Тимур" - Сообщение в чате:
"Готово! Задание выполнено." - Слово в игре «Поле чудес»:
"ЭЛЕКТРИЧЕСТВО"
2. Целое число — int, integer
Что это? Число без дробной части — ни запятых, ни точек. Может быть отрицательным: -17, 0, 42, 1000000.
Важно: не все целые числа равны с точки зрения памяти. Некоторые языки (например, Python) позволяют хранить огромные целые числа, но платят за это гибкостью и скоростью. Другие (например, C# или Java) выделяют строго фиксированный размер — и если число «не влезает», возникает ошибка переполнения.
Как хранится? В двоичной системе. Например, число 13 в 4-байтовом формате выглядит как 00000000 00000000 00000000 00001101. Первый бит — знак: 0 = положительное, 1 = отрицательное (но для отрицательных чисел используется дополнительный код — это уже детали, пока можно не запоминать).
Примеры использования:
- Счётчик жизней в игре:
3 - Возврат индекса элемента в списке:
0,1,2… - Год выпуска:
2025
3. Число с запятой (с плавающей точкой) — float
Что это? Число, у которого есть дробная часть: 3.14, -0.001, 2.0, 6.02e23 (это научная запись: 6.02 × 10²³).
⚠️ Внимание: в программировании всегда используется точка, а не запятая: 3.14, а не 3,14. Это международный стандарт — запятая могла бы восприниматься как разделитель аргументов.
Но! Числа с плавающей точкой — приближённые. Это не баг, а особенность: компьютер хранит их не как точные дроби (типа ⅓), а как сумму степеней двойки. Поэтому иногда возникает «странное» поведение:
0.1 + 0.2 # → 0.30000000000000004
Это не ошибка. Это как если бы вы пытались записать 1/3 в десятичной системе: 0.333... — бесконечно. Так и компьютер: не может точно представить 0.1 в двоичной системе, поэтому накапливается погрешность.
Примеры использования:
- Температура:
36.6 - Координаты объекта на экране:
x = 102.5,y = 204.75 - Вероятность события:
0.75
4. Булево значение — bool, boolean: True и False
Что это? Ответ на вопрос «да/нет», «включено/выключено», «выполнено/не выполнено». Только два возможных значения:
True— правда, истина, «да»;False— ложь, «нет».
Названо в честь Джорджа Буля — математика XIX века, заложившего основы логики, которую сейчас используют все компьютеры.
Как хранится? Чаще всего — 1 бит (минимум), но на практике — 1 байт (из соображений выравнивания памяти). False = 0, True = 1.
Где используется? Везде, где нужна проверка:
- Условия:
if пользователь_вошёл: - Циклы:
while игра_идёт: - Флаги:
готово = False
💡 Интересный факт: в Python почти всё можно привести к bool. Пустая строка "" → False, ноль 0 → False, None → False. А " " (пробел), 1, "False" (это текст!) → True. Это называется истинность объекта — но это уже продвинутая тема.
5. Ничего — None (Python), null (JavaScript, Java и др.)
Что это? Не «пусто», не «ноль», не «ошибка» — а специальное значение, означающее отсутствие значения.
Представьте: у вас есть конверт с надписью «Подарок». Если конверт пуст — это не значит, что там лежит «ноль подарков». Просто ничего не положили. None — как такой пустой конверт.
Зачем нужно?
- Чтобы показать, что переменная ещё не заполнена:
результат_поиска = None # пока не искали - Чтобы вернуть из функции «ничего полезного»:
def вывести_приветствие():
print("Привет!")
return None # можно не писать — по умолчанию
⚠️ Опасность: если попытаться использовать None, как число или текст — будет ошибка. Например: None + 5 → TypeError.
Как это всё работает вместе? Диаграмма памяти
Вот как это может выглядеть «под капотом»:
Что здесь происходит?
- Каждая переменная — это имя (ярлык), привязанное к участку памяти.
- Размер участка зависит от типа: строки динамичны (чем длиннее — тем больше), числа и bool — фиксированы (в рамках одного языка).
Noneтоже занимает место — потому что компьютер должен знать, что там «ничего», а не «мусор от прошлой программы».
Задачи для закрепления
🔹 Уровень 1 (8–10 лет)
- Напишите 5 переменных: имя, возраст, рост, любит_мороженое, лучший_друг. Присвойте им подходящие значения. Какой тип у каждой?
- Что будет, если написать:
Как исправить, чтобы получить
a = "5"
b = 3
print(a + b)8? - Попробуйте угадать тип у:
"""0"0FalseNone
🔹 Уровень 2 (11–13 лет)
- Почему
0.1 + 0.2 != 0.3в программировании? Проверьте в Python или JS. Попробуйте объяснить, не используя слово «ошибка». - Напишите программу, которая спрашивает имя и возраст, а потом выводит:
"Привет, Алиса! Через 5 лет тебе будет 17."
(подсказка: возраст нужно превратить из строки в число!) - Что вернёт выражение:
bool(""),bool(" "),bool(0),bool(-1),bool(None)? Проверьте и объясните закономерность.
🔹 Уровень 3 (14–16 лет)
- В Python можно написать:
Почему это работает? Как называется такая типизация? В каких языках так нельзя? Приведите пример.
x = 10
print(type(x))
x = "десять"
print(type(x)) - Придумайте ситуацию, где использование
Noneлучше, чем0,""илиFalse. Обоснуйте. - Нарисуйте свою версию «библиотеки типов данных»: какие «залы» есть? Где лежат числа с дробью? Почему строки — в отдельном крыле?
Часть 2: Когда одного значения недостаточно
Составные типы и работа с коллекциями
Вы уже умеете хранить одно значение: имя, возраст, ответ «да/нет». Но реальная программа редко работает с единичными данными. Она управляет наборами: списком друзей, перечнем уровней в игре, каталогом книг, таблицей рекордов.
Для этого существуют составные (коллекционные) типы данных — контейнеры, которые могут держать много значений одновременно. Их называют по-разному: структуры данных, коллекции, последовательности. Мы рассмотрим самые распространённые.
📌 Важно: составные типы — это не «новая магия». Это всего лишь способы организовать простые типы (числа, строки, bool и т.д.) в удобные группы. Как ящики, разделённые на ячейки.
1. Список — list
«Коробка с пронумерованными отделениями»
Что это? Упорядоченная последовательность элементов. Можно добавлять, удалять, менять — список изменяем.
Пример:
друзья = ["Алиса", "Борис", "Вика"]
оценки = [5, 4, 5, 3, 5]
смешанное = ["Тимур", 12, True, None]
Особенности:
- Элементы нумеруются с нуля:
друзья[0] → "Алиса",
друзья[2] → "Вика". - Длина может меняться:
друзья.append("Глеб")→ список стал длиннее. - Внутри могут быть любые типы — даже другие списки:
класс = [
["Алиса", 12, "математика"],
["Борис", 13, "физика"]
]
Как хранится?
Внутри — массив ссылок (в Python) или непрерывный блок памяти (в C++). При добавлении в конец — быстро. При вставке в середину — медленнее: нужно «сдвинуть» все последующие элементы.
Аналогия:
Представьте книжную полку, где каждая книга имеет номер (0, 1, 2…). Вы можете:
- Взять книгу №1 — быстро;
- Поставить новую книгу в конец — быстро;
- Вставить книгу между №1 и №2 — придётся сдвинуть все справа.
Где используется:
- История сообщений в чате;
- Список уровней в игре;
- Результаты поиска (10 первых ссылок);
- Корзина товаров.
2. Кортеж — tuple
«Коробка с запаянными отделениями»
Что это? Тоже упорядоченная последовательность — но неизменяемая. После создания нельзя ни добавить, ни заменить, ни удалить элемент.
Пример:
координаты = (100, 200)
цвет = (255, 128, 0) # RGB: оранжевый
дата = (2025, 11, 10) # год, месяц, день
Особенности:
- Записывается в круглых скобках (но можно и без — главное, запятая:
x = 5,— это кортеж из одного элемента!); - Элементы тоже индексируются с нуля:
координаты[0] → 100; - Быстрее списка при чтении (меньше служебной информации);
- Можно использовать как ключ в словаре (список — нельзя!).
Почему неизменяемость — это хорошо?
Потому что гарантирует целостность данных. Если вы передаёте координаты точки в функцию, вы уверены: её никто «случайно» не сдвинет внутри. Это как отправить посылку в запломбированной коробке, а не в рюкзаке с молнией.
Аналогия:
GPS-координаты места: широта и долгота — фиксированная пара. Изменить их нельзя — можно только получить новую пару для другого места.
3. Словарь — dict
«Телефонная книга»
Что это? Набор пар «ключ → значение». Порядок не гарантируется (в старых версиях Python), но в новых — сохраняется (как побочный эффект реализации).
Пример:
профиль = {
"имя": "Алиса",
"возраст": 12,
"город": "Казань",
"хобби": ["роботы", "математика"]
}
Особенности:
- Доступ — по ключу, а не по номеру:
профиль["имя"] → "Алиса"
(а непрофиль[0]— это было бы ненадёжно: вдруг порядок поменяется?); - Ключами могут быть только неизменяемые типы: строки, числа, кортежи. Списки — нельзя;
- Очень быстро ищет по ключу — даже если в словаре миллион записей.
Как это работает?
Компьютер вычисляет хеш от ключа — как «отпечаток пальца» строки "имя" — и по нему находит ячейку в памяти. Это как если бы в телефонной книге не листали страницы, а сразу шли в нужную ячейку по первым буквам фамилии.
Где используется:
- Настройки программы (
настройки["звук"] = True); - JSON-данные (почти все API в интернете отдают данные именно в виде словарей);
- Счётчики:
{ "кот": 5, "собака": 3 }.
4. Множество — set
«Мешок с уникальными фишками»
Что это? Неупорядоченная коллекция уникальных элементов. Нет дубликатов. Нет порядка. Можно быстро проверять: «есть ли такой элемент?»
Пример:
теги = {"роботы", "математика", "программирование"}
теги.add("игры") # добавит, если ещё нет
теги.add("роботы") # ничего не сделает — уже есть!
Особенности:
- Записывается в фигурных скобках, но без
ключ: значение; - Поддерживает операции из теории множеств:
A ∪ B— объединение (|),
A ∩ B— пересечение (&),
A − B— разность (-). - Проверка принадлежности (
"роботы" in теги) работает за постоянное время — O(1), даже для миллиона элементов.
Аналогия:
Мешок с буквами из игры «Эрудит». Вы не знаете, в каком порядке они лежат. Но вы легко можете:
- проверить, есть ли буква
К; - высыпать все буквы из двух мешков и убрать повторы — это объединение;
- оставить только те, что есть в обоих — пересечение.
Где используется:
- Удаление дубликатов из списка:
list(set(список)); - Быстрая проверка «уже видели этот URL?» при парсинге сайтов;
- Поиск общих друзей:
друзья_Алисы ∩ друзья_Бориса.
Как выбирать подходящий тип?
| Задача | Подходит | Почему |
|---|---|---|
| Хочу хранить последовательность и менять её | list | Можно добавлять, удалять, менять |
| Хочу передать координаты и быть уверенным, что их не исказят | tuple | Неизменяемость = безопасность |
Хочу обращаться к данным по смысловому имени ("город", а не [2]) | dict | Читаемо, надёжно, быстро |
| Хочу быстро проверять наличие и избегать дублей | set | Уникальность + скорость поиска |
💡 Совет: начинайте со списка или словаря — они самые «дружелюбные». Переходите к кортежам и множествам, когда появится конкретная причина: безопасность данных или производительность.
Приведение типов: «перевод» из одного типа в другой
Иногда данные приходят в «неправильной» упаковке. Например, пользователь ввёл возраст как текст "12", а вам нужно прибавить 1 — но "12" + 1 не сработает.
Для этого существуют функции приведения типов:
| Из → В | Функция | Пример |
|---|---|---|
str → int | int() | int("12") → 12 |
str → float | float() | float("3.14") → 3.14 |
int/float → str | str() | str(42) → "42" |
любой → bool | bool() | bool(0) → False, bool("0") → True |
⚠️ Опасные места:
int("3.14")— ошибка! Надо сначала вfloat, потом вint:int(float("3.14"));int("")— ошибка. Пустая строка не число;bool("False")→True, потому что"False"— не пустая строка.
Правило безопасности:
Перед приведением — проверяйте, можно ли это сделать.
В Python:текст = input("Возраст: ")
if текст.isdigit(): # состоит только из цифр?
возраст = int(текст)
else:
print("Нужно ввести число!")
Типизация в разных языках: статическая vs динамическая
Вы уже видели, что в Python можно написать:
x = 5
x = "пять"
— и это нормально. А в Java так нельзя. Почему?
Динамическая типизация (Python, JavaScript, PHP)
- Тип «приклеен» к значению, а не к переменной;
- Переменная — просто ярлык, который можно переклеить на другую коробку;
- Гибко, быстро для прототипов — но ошибки выявляются во время выполнения.
Статическая типизация (C#, Java, TypeScript, Rust)
- Тип «приклеен» к переменной при объявлении:
int возраст = 12;
// возраст = "двенадцать"; ← ошибка на этапе компиляции! - Компилятор проверяет соответствие до запуска;
- Требует чуть больше кода, но даёт уверенность и подсказки в редакторе.
🔹 TypeScript — интересный гибрид: JavaScript + опциональная статическая типизация. Можно начать без типов, а потом постепенно добавлять — как ремень безопасности в машине.
Как это всё складывается в реальном проекте?
Представим игру «Космический зоопарк» для 10-летних. Вот как могут выглядеть данные:
# Один питомец — словарь
питомец = {
"имя": "Звёздочёт",
"вид": "Пульсарный кот",
"энергия": 85, # int
"сытость": 72.5, # float
"спит": False, # bool
"навыки": ["телепорт", "мигание"], # list
"координаты": (10, 25), # tuple
}
# Весь зоопарк — список питомцев
зоопарк = [питомец, другой_питомец, ...]
# Глобальные настройки — словарь
настройки = {
"звук": True,
"музыка": 0.8,
"тема": "тёмная"
}
# Достижения — множество
достижения = {"первый_питомец", "100_очков"}
Здесь:
- Простые типы (
int,float,bool) — для состояний; str— для всего, что «читает человек»;list— для упорядоченных, изменяемых наборов;tuple— для неизменяемых пар/троек (координаты, размеры);dict— для объектов с именованными свойствами;set— для флагов «уже сделано».
Это и есть архитектура данных — даже в детской игре.
Задачи для закрепления (часть 2)
🔹 Уровень 1 (8–10 лет)
- Создайте список из 5 любимых мультфильмов. Выведите второй и последний.
- Сделайте словарь
игрушкас ключами:"название","цвет","материал". Добавьте свою игрушку. - Что выведет код?
(Попробуйте угадать до запуска!)
a = (1, 2)
b = [1, 2]
a[0] = 5 # ?
b[0] = 5 # ?
🔹 Уровень 2 (11–13 лет)
- Напишите программу, которая:
- спрашивает 3 имени друга;
- сохраняет их в списке;
- добавляет
"и я"в конец; - выводит:
"Мы пошли в парк: Алиса, Борис, Вика и я."
- У вас есть два списка:
математика = ["Алиса", "Борис", "Вика"]
физика = ["Борис", "Глеб", "Алиса"]
Как найти тех, кто учится и там, и там? Используйте множества. - Почему так можно:
а так — нельзя:
d = {}
d[(1, 2)] = "точка"d[[1, 2]] = "ошибка" # ← почему?
🔹 Уровень 3 (14–16 лет)
- Придумайте структуру данных для хранения расписания уроков на неделю.
Требования:- Можно спросить: «Какие уроки в понедельник?»
- Можно спросить: «Когда урок “информатики”?»
- Можно добавить кабинет к каждому уроку.
Реализуйте на Python.
- В TypeScript можно написать:
Что означает
let x: number | string = 5;
x = "пять";number | string? Как это называется? Чем это лучше простогоany? - Почему в Python
[] == []→True, но[] is []→False?
(Подсказка:==сравнивает содержимое,is— идентичность объекта.)